#! python3
# encoding=utf-8

from uart import Uart
from crc import crc
import time
import threading

class Humiture:
    '''温湿度计'''

    # 寄存器类型
    # 保持寄存器地址
    __ID_REG_ADDR = 0x0a
    __BAUD_REG_ADDR = 0x0b
    # 输入寄存器地址
    __TEMPERATURE_REG_ADDR = 0x00
    __HUMIDITY_REG_ADDR = 0x01

    # 功能码定义
    __AD_MAINTAIN_REG = 0x03
    __WRITE_MAINTAIN_REG = 0x06
    __AD_INPUT_REG = 0x04   # 温湿度
    
    def __init__(self, id) -> None:
        self.id = id
        self.humitureflag = False
        # self.threadLock = threading.Lock()

    def tranmiteMethodRegistor(self, transmit = None, receiver = None):
        self.transmit = transmit
        self.receiver = receiver

    def dataParse(self, data):
        lcrc = []
        for i in range(len(data)):
            if data[i] == self.id:
                if data[i + 1] == self.__AD_MAINTAIN_REG:
                    pass
                elif data[i + 1] == self.__AD_INPUT_REG:
                    pass
                    datalen = data[i + 2]
                    lcrc += data[i + datalen + 3: i +datalen + 5]
                elif data[i + 1] == self.__WRITE_MAINTAIN_REG:
                    pass
                else:
                    return None
                if lcrc == crc.crc16(data[i:i + datalen + 3], True):
                    return data[i:i + datalen + 3]
                else:
                    return None
        return None

    def handler(self, data):
        pass
        # print("Received:%s\n" % bytes(data).hex())
        if len(data) < 9:
            print("Error")
            return
        
        tmp = self.dataParse(data)
        if not tmp:
            return -1
        data.clear()
        data += tmp
        if data[0] != self.id:
            return
        
        if data[1] == self.__AD_MAINTAIN_REG:
            pass
            id = int.from_bytes(data[3:5], "big")
            baud = self.__no2baud(int.from_bytes(data[3:5], "big"))
            pass
        elif data[1] == self.__WRITE_MAINTAIN_REG:
            pass
            if self.__ID_REG_ADDR == int.from_bytes(data[2:4], "big"):
                pass
                print("ID have been write %d\n" % int.from_bytes(data[4:6], "big"))
            elif self.__BAUD_REG_ADDR == int.from_bytes(data[2:4], "big"):
                pass
                print("Baud have been write %d\n" % self.__no2baud(int.from_bytes(data[4:6], "big")))
        elif data[1] == self.__AD_INPUT_REG:
            pass
            # self.humiture.clear()
            temperature = int.from_bytes(data[3:5], "big") / 10
            
            humidity = int.from_bytes(data[5:7],"big") / 10
    
            # self.humiture.append(temperature)
            # self.humiture.append(humidity)
            # print(temperature, humidity)
            # self.threadLock.acquire()
            self.humitureflag = True
            # self.threadLock.release()
            return (1, temperature, humidity)

    def __no2baud(self, no):
        if no == 0:
            return 4800
        elif no == 1:
            return 9600
        elif no == 2:
            return 14400
        elif no == 3:
            return 19200
        elif no == 4:
            return 38400
        elif no == 5:
            return 56000
        elif no == 6:
            return 57600
        elif no == 7:
            return 115200
        elif no == 8:
            return 128000
        elif no == 9:
            return 256000
        
    def __baud2no(self, baud):
        if baud == 4800:
            return 0
        elif baud == 9600:
            return 1
        elif baud == 14400:
            return 2
        elif baud == 19200:
            return 3
        elif baud == 38400:
            return 4
        elif baud == 56000:
            return 5
        elif baud == 57600:
            return 6
        elif baud == 115200:
            return 7
        elif baud == 128000:
            return 8
        elif baud == 256000:
            return 9
        
    def __joint(self, cmd, eData):
        pass
        data = [self.id]
        data.append(cmd)
        data += eData
        data += crc.crc16(data, True)
        return data  

    def __dataTransmit(self, data):
        if self.transmit == None:
            print(data)
            return
        # print("%s\n" % bytes(data).hex(" "))
        print("%s\n" % bytes(data).hex())
        self.transmit(data)

    def humitureRead(self, cmd, addr:int):
        data = []
        data += addr.to_bytes(2, "big")
        data += (2).to_bytes(2, "big")
        self.__dataTransmit(self.__joint(cmd, data))

    def idRead(self, cmd, addr:int):
        data = []
        data += addr.to_bytes(2, "big")
        data += (2).to_bytes(2, "big")
        self.__dataTransmit(self.__joint(cmd, data))

    def baudRead(self, cmd, addr:int):
        self.idRead(addr)
    
    def writeId(self, cmd, addr, id):
        data = []
        data += addr.to_bytes(2, "big")
        data += id.to_bytes(2, "big")
        self.__dataTransmit(self.__joint(cmd, data))

    def writeBaud(self, cmd, addr, baud):
        data = []
        data += addr.to_bytes(2, "big")
        data += self.__baud2no(baud).to_bytes(2, "big")
        self.__dataTransmit(self.__joint(cmd, data))
        
